package zju.ccnt.fileserverProxy.repository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import zju.ccnt.fileserverProxy.exception.FileServerNotFound;

import java.util.List;
import java.util.Map;

/**
 * Created by zha on 14/11/27.
 */
@Repository
public class FileServerRepository {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

//    @Value("${fileserver.set.name}")
    //list，记录fileservername,右边为新插入的服务器，优先考虑
    private static final String FILE_SERVER_LIST_NAME = "dfsservers";

    /**
     * 获取服务器名，从索引下标start,获取后面
     * @param start
     * @param rangeSize
     * @return
     */
    public List<String> getFileServerRange(int start, int rangeSize){
        return getFileServer(start, start+rangeSize);
    }

    private List<String> getFileServer(int start, int end){
        return redisTemplate.opsForList().range(FileServerRepository.FILE_SERVER_LIST_NAME, start, end);
    }

    /**
     * 获取所有服务器名
     * @return
     */
    public List<String> getAllFileServerName(){
        return getFileServer(0, -1);
    }

    public long countFileServer(){
        return redisTemplate.opsForList().size(FileServerRepository.FILE_SERVER_LIST_NAME);
    }

    /**
     * 从尾部START获取服务器名，获取数量为rangesize, 包括START
     * @param start
     * @param rangeSize
     * @return
     */
    public List<String> getFileServersFromTail(int start, int rangeSize){
        return getFileServer(rangeSize * -1 + start + 1, start);
    }

    /**
     * 获取指定服务器名的服务器详情
     * @param fileServerName
     * @return
     */
    public Map<String, String> getFileServerDetail(String fileServerName){
        BoundHashOperations<String, String, String> hashOperations = redisTemplate.boundHashOps(fileServerName);
        Map<String, String> res = hashOperations.entries();
        if (res == null) throw new FileServerNotFound(fileServerName);
        return res;
    }

    public String removeFileServer(String fileServerName){
        long result = redisTemplate.opsForList().remove(FileServerRepository.FILE_SERVER_LIST_NAME, 0, fileServerName);
        if (result < 1) throw new FileServerNotFound(fileServerName);
        return fileServerName;
    }

    public void leftPush(String fileServerSetName){
        redisTemplate.opsForList().leftPush(FileServerRepository.FILE_SERVER_LIST_NAME, fileServerSetName);
    }

}
